package org.dut.community.controller;

import org.dut.community.entity.*;
import org.dut.community.event.EventProducer;
import org.dut.community.service.CommentService;
import org.dut.community.service.DiscussPostService;
import org.dut.community.service.LikeService;
import org.dut.community.service.UserService;
import org.dut.community.util.CommunityConstant;
import org.dut.community.util.CommunityUtil;
import org.dut.community.util.HostHolder;
import org.dut.community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import java.util.*;

@Controller
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {
    @Autowired
    private DiscussPostService discussPostService;
    @Autowired
    private HostHolder hostHolder;
    @Autowired
    private UserService userService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private LikeService likeService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private EventProducer eventProducer;

    // 发布帖子
    @ResponseBody
    @RequestMapping(path ="/add",method = RequestMethod.POST)
    public String addDiscussPost(String title, String content) {
        User user = hostHolder.getUser();
        if(user == null) {
            return CommunityUtil.getJSONString(403, "你还没有登录！");
        }
        if(title == null || title.trim().isEmpty()
                || content == null || content.trim().isEmpty()) {
            return CommunityUtil.getJSONString(400, "标题或内容不能为空！");
        }
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle(title);
        post.setContent(content);
        post.setCreateTime(new Date());
        discussPostService.addDiscussPost(post);
        // 通知粉丝有未读帖子
        discussPostService.notifyFollowersNewPost(user.getId(), post.getId());

        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, post.getId());

        Event event = Event.builder()
                            .topic(TOPIC_PUBLISH)
                            .userId(user.getId())
                            .entityType(ENTITY_TYPE_POST)
                            .entityId(post.getId())
                            .build();
        eventProducer.fireEvent(event);
        return CommunityUtil.getJSONString(0, "发布成功！");
    }

    // 进入更新页面
    @RequestMapping(path ="/update/{postId}",method = RequestMethod.GET)
    public String updateDiscussPost(@PathVariable("postId") int postId, Model model) {
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        if(post == null || post.getId() != hostHolder.getUser().getId() || post.getStatus() == 2) {
            return "site/error/404";
        }
        model.addAttribute("title", post.getTitle());
        model.addAttribute("content", post.getContent());
        model.addAttribute("id",postId);
        return "site/update-posts";
    }

    // 更新帖子
    @ResponseBody
    @RequestMapping(path = "/update/{postId}",method = RequestMethod.POST)
    public String updateDiscussPost(@PathVariable("postId") int postId,String title,String content) {
        User user = hostHolder.getUser();
        if(user == null) {
            return CommunityUtil.getJSONString(403, "你还没有登录！");
        }
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        if(post == null || post.getId() != hostHolder.getUser().getId()) {
            return CommunityUtil.getJSONString(403, "你没有权限修改此帖子！");
        }
        post.setTitle(title);
        post.setContent(content);
        post.setCreateTime(new Date());
        discussPostService.updateDiscussPost(post);
        return CommunityUtil.getJSONString(0, "修改成功！");
    }

    // 跳转发布页面
    @RequestMapping(path = "/publish",method = RequestMethod.GET)
    public String getPublishPage(Model model) {
        return "site/publish-posts";
    }

    // 跳转帖子详情页
    @RequestMapping(path = "/detail/{discussPostId}",method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page,
            @RequestParam(name = "orderMode",defaultValue = "0")int orderMode) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        User user = hostHolder.getUser();
        if(post.getStatus() == 2 && (user == null ||
                (user.getType() != 1 && user.getType() != 2 && user.getId() != post.getUserId()))){
            return "/site/error/404";  // 非管理员、版主、帖子主人无法查看已删除帖子
        }

        String content = HtmlUtils.htmlUnescape(post.getContent());
        post.setContent(content);
        model.addAttribute("post",post);

        // 作者
        user = userService.findUserById(post.getUserId());
        model.addAttribute("user",user);

        // 点赞数量 和 点赞状态
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeCount",likeCount);
        int likeStatus = hostHolder.getUser() == null? 0:
                likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_POST,discussPostId);
        model.addAttribute("likeStatus",likeStatus);

        // 评论分页信息
        page.setLimit(5);
        page.setPath("/discuss/detail/"+discussPostId);
        page.setRows(post.getCommentCount());
        List<Comment> commentList = commentService.findCommentsByEntity(
                CommunityConstant.ENTITY_TYPE_POST, discussPostId, page.getOffset(), page.getLimit(),orderMode);

        // 评论和回复
        List<Map<String,Object>> commentVoList = new ArrayList<>();
        if(commentList != null && !commentList.isEmpty()) {
            for(Comment comment : commentList) {
                Map<String,Object> commentVo = new HashMap<>();
//                comment.setContent(HtmlUtils.htmlUnescape(comment.getContent()));
                // 评论
                commentVo.put("comment",comment);
                // 作者
                commentVo.put("user",userService.findUserById(comment.getUserId()));
                // 赞
                likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeCount",likeCount);
                likeStatus =  hostHolder.getUser() == null? 0:
                        likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT,comment.getId());
                commentVo.put("likeStatus",likeStatus);
                // 回复 统一按时间倒序排序
                List<Comment> replyList = commentService.findCommentsByEntity(
                        CommunityConstant.ENTITY_TYPE_COMMENT,comment.getId(), 0,Integer.MAX_VALUE,1);

                List<Map<String,Object>> replyVoList = new ArrayList<>();
                if(replyList != null && !replyList.isEmpty()) {
                    for(Comment reply : replyList) {
                        Map<String,Object> replyVo = new HashMap<>();
                        // 回复
                        replyVo.put("reply",reply);
                        // 回复者
                        replyVo.put("user",userService.findUserById(reply.getUserId()));
                        // 回复的目标用户
                        User target = reply.getUserId() == 0? null: userService.findUserById(reply.getTargetId());
                        replyVo.put("target",target);
                        // 赞和赞状态
                        likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeCount",likeCount);
                        likeStatus =  hostHolder.getUser() == null? 0:
                                likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT,reply.getId());
                        replyVo.put("likeStatus",likeStatus);

                        replyVoList.add(replyVo);
                    }
                }
                commentVo.put("replyList",replyVoList);
                // 回复数量
                commentVo.put("replyCount",replyList.size());

                commentVoList.add(commentVo);
            }
        }
        model.addAttribute("commentList",commentVoList);
        model.addAttribute("commentCount",commentVoList.size());

        // 帖子访问量
        discussPostService.updatePostReadCount(discussPostId);
        //post:read:postId
        String redisKey = RedisKeyUtil.getPostReadKey(discussPostId);
        model.addAttribute("postReadCount",redisTemplate.opsForValue().get(redisKey)==null?0:redisTemplate.opsForValue().get(redisKey));

        model.addAttribute("orderMode",orderMode);
        return "/site/discuss-detail";
    }

    // 置顶
    @ResponseBody
    @RequestMapping(path = "/top",method = RequestMethod.POST)
    public String setTop(int id) {
        DiscussPost post = discussPostService.findDiscussPostById(id);
        int type = post.getType() == 1 ?0:1;
        discussPostService.updateType(id, type);
        Map<String,Object> map = new HashMap<>();
        map.put("type",type);

        // 同步给elasticsearch(通过kafka)
        Event event = Event.builder()
                .topic(TOPIC_PUBLISH)
                .entityType(ENTITY_TYPE_POST)
                .entityId(id)
                .userId(hostHolder.getUser().getId())
                .build();
        eventProducer.fireEvent(event);
        return CommunityUtil.getJSONString(0, null,map);
    }

    // 加精
    @RequestMapping(path = "/wonderful", method = RequestMethod.POST)
    @ResponseBody
    public String setWonderful(int id) {
        DiscussPost post = discussPostService.findDiscussPostById(id);
        int status = post.getStatus() == 1 ?0:1;
        discussPostService.updateStatus(id, status);
        Map<String,Object> map = new HashMap<>();
        map.put("status",status);

        Event event = Event.builder()
                .topic(TOPIC_PUBLISH)
                .entityType(ENTITY_TYPE_POST)
                .entityId(id)
                .userId(hostHolder.getUser().getId())
                .build();
        eventProducer.fireEvent(event);

        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(0, null,map);
    }

    // 删除 允许管理员，版主，帖子作者删除
    @RequestMapping(path = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String setDelete(int id){
        // 检查权限
        DiscussPost post = discussPostService.findDiscussPostById(id);
        if(post == null) {
            return CommunityUtil.getJSONString(404,"帖子不存在");
        }
        User user = hostHolder.getUser();
        boolean isAdmin = userService.getAuthorities(user.getId()).stream()
                .anyMatch(auth -> AUTHORITY_ADMIN.equals(auth.getAuthority()));

        boolean isModerator = userService.getAuthorities(user.getId()).stream()
                .anyMatch(auth -> AUTHORITY_MODERATOR.equals(auth.getAuthority()));

        if(user.getId() != post.getUserId() && !isAdmin && !isModerator) {
            return CommunityUtil.getJSONString(403,"您没有权限删除此帖子");
        }
        DiscussPost discussPost = discussPostService.findDiscussPostById(id);
        int status = post.getStatus()==2?0:2;
        discussPostService.updateStatus(id, status);

        // 这时同步es应该是删除帖子
        Event event = Event.builder()
                .topic(TOPIC_DELETE)
                .entityType(ENTITY_TYPE_POST)
                .entityId(id)
                .userId(hostHolder.getUser().getId())
                .build();
        eventProducer.fireEvent(event);

        return CommunityUtil.getJSONString(0);
    }



}
